import { List } from 'Linqts';

import { FilterOperateEntity, FilterOperateEnum } from '@/enums/filterOperateEnum';
import { isFunction } from '@/utils/is';
import { EnumSchema, ListNode } from '#/common';

// #region 获取URL中Hash串中的查询参数值
/**
 * 获取URL中Hash串中的查询参数值
 * @param url URL字符串
 * @param name 参数名
 */
export function getHashURLSearchParams(url: string, name: string): string | null {
  if (url.indexOf('#') >= 0) {
    url = subStr(url, '#');
  }
  if (url.indexOf('?') >= 0) {
    url = subStr(url, '?');
  }
  const params = new URLSearchParams(url);
  return params.get(name);
}
// #endregion
// #region 提供首尾字符串截取中间的字符串
/**
 * 提供首尾字符串截取中间的字符串
 * @param str 待截取的字符串
 * @param start 起始的字符串
 * @param end 结束的字符串
 */
export function subStr(
  str: string,
  start: string | null = null,
  end: string | null = null,
): string {
  let startIndex = 0;
  let endIndex = str.length;
  if (start) {
    startIndex = str.indexOf(start) + start.length;
  }
  if (end) {
    endIndex = str.indexOf(end);
  }
  // return str.substr(startIndex, endIndex - startIndex);
  return str.substring(startIndex, endIndex);
}
// #endregion
// #region 从集合中删除符合条件的项
/**
 * 从集合中删除符合条件的项
 * @param items 集合
 * @param exp 删除项查询表达式
 */
export function remove<T>(items: Array<T>, exp: (value: T, index: number, obj: T[]) => boolean) {
  const index = items.findIndex(exp);
  items.splice(index, 1);
  return items;
}
// #endregion
// #region 值转文字
/**
 * 值转文字
 * @param id 待转换的值
 * @param array 数据节点集合
 * @param defaultText 转换失败时的默认文字
 */
export function valueToText(
  id: number,
  array: { id: number; text: string }[] | ListNode[],
  defaultText: string | null = null,
) {
  let text = defaultText == null ? id.toString() : defaultText;
  array.forEach((item) => {
    if (item.id === id) {
      text = item.text;
      return false;
    }
    return true;
  });
  return text;
}
// #endregion
// #region 展开集合拼接字符串
/**
 * 展开集合拼接字符串
 * @param array 待展开的集合
 * @param separator 分隔符
 */
export function expandAndToString(array: Array<any>, separator = ',') {
  let result = '';
  if (!array || !array.length) {
    return result;
  }
  array.forEach((item) => {
    result = result + item.toString() + separator;
  });
  return result.substring(0, result.length - separator.length);
}
// #endregion

// #region 获取文件扩展名
/**
 * 获取文件扩展名
 * @param filename 文件名称
 * @param includeSeparator 是否包含后缀名前置分隔符，默认true
 */
export function getFileExtname(filename: string, includeSeparator = true) {
  const separator = '.';
  // // 方法1 PS：不好用
  // const patternFileExtension = /\.([0-9a-z]+)(?:[\?#]|$)/i;
  // const fileExtname = filename.match(patternFileExtension);
  // return fileExtname?.toString() || '';

  // // 方法2
  // const result = filename.split(separator);
  // return result[result.length - 1];

  // 方法3
  let fileExtension = filename.split(separator).pop();
  fileExtension = fileExtension || '';
  if (fileExtension && includeSeparator) {
    return `${separator}${fileExtension}` || '';
  }
  return fileExtension || '';
}
// #endregion
// #region 去除文件扩展名
/**
 * 去除文件扩展名
 * @param filename 文件名称
 */
export function removeFileExtname(filename: string) {
  const fileExtension = getFileExtname(filename, true);
  const fileNameWithoutExtension = filename.replace(`${fileExtension}`, '');
  return fileNameWithoutExtension || '';
}
// #endregion
// #region 获取文件的Base64格式
/**
 * 获取文件的Base64格式
 * @param file 文件的信息
 * @param callback 转换成Base64后的回调
 */
export function getBase64(file: File, callback: (base64String: string) => void) {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result as string));
  reader.readAsDataURL(file);
}
// #endregion
// #region 获取文件的Base64格式
/**
 * 获取文件的Base64格式
 * @param file 文件的信息
 */
export function getBase64WithFile(file: File) {
  return new Promise<{
    result: string;
    file: File;
  }>((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve({ result: reader.result as string, file });
    reader.onerror = (error) => reject(error);
  });
}
// #endregion

// #region 获取Base64格式的文件对象
/**
 * 获取Base64格式的文件对象
 * @param base64Data Base64数据
 * @param fileName 文件名称
 */
export function getFileWithBase64(base64Data: string, fileName: string) {
  const arr = base64Data.split(',');
  if (arr && arr[0] && arr[1]) {
    const arr0match = arr[0].match(/:(.*?);/);
    let mime = '';
    if (arr0match) {
      mime = arr0match[1];
    }
    // const bytes = atob(arr[1]); // 解码base64
    const bytes = Buffer.from(arr[1], 'base64').toString(); // 解码base64
    let n = bytes.length;
    const ia = new Uint8Array(n);
    while (n--) {
      ia[n] = bytes.charCodeAt(n);
    }
    return new File([ia], fileName, { type: mime });
  }
  return null;
}
// #endregion

// #region 获取筛选操作实体集合
/**
 * 获取筛选操作实体集合
 * @param operates 筛选操作枚举集合
 * @returns 筛选操作实体集合
 */
export function getOperateEntities(operates: FilterOperateEnum[]): FilterOperateEntity[] {
  return new List(operates).Select((m: FilterOperateEnum) => new FilterOperateEntity(m)).ToArray();
}
// #endregion

// #region 根据远程方法转换枚举架构集合
/**
 * 根据远程方法转换枚举架构集合
 * @param apiFunction 远程方法
 * @param labelName 描述字段
 * @param valueName 值字段
 * @returns 枚举架构集合
 */
export async function readNode(
  apiFunction: () => Promise<any[]>,
  labelName: string,
  valueName: string,
): Promise<EnumSchema[]> {
  const enumSchema: EnumSchema[] = [];
  if (apiFunction && isFunction(apiFunction)) {
    const nodes = await apiFunction();
    if (nodes && nodes.length > 0) {
      nodes.forEach((item) => {
        enumSchema.push({
          key: item[valueName],
          label: item[labelName],
          value: item[valueName],
        });
      });
    }
  }
  return enumSchema;
}
// #endregion

// #region 比较两个字符串数组是否相等（忽略顺序）
/**
 * 比较两个字符串数组是否相等（忽略顺序）
 * @param arr1 第一个字符串数组
 * @param arr2 第二个字符串数组
 * @returns 是否相等
 */
export function isStringArrayEqual(arr1: string[], arr2: string[]): boolean {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
    return false;
  }

  if (arr1.length !== arr2.length) {
    return false;
  }

  // 创建数组副本并排序
  const sortedArr1 = [...arr1].sort();
  const sortedArr2 = [...arr2].sort();

  // 逐个比较元素
  return sortedArr1.every((item, index) => item === sortedArr2[index]);
}
// #endregion
